package com.yanfan.rs232;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yanfan.common.utils.GpsCoordinateUtils;
import com.yanfan.framework.manager.AsyncManager;
import com.yanfan.iot.domain.Device;
import com.yanfan.iot.service.IDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
public class RestapiMessage {

    // 高德地图逆地理编码API地址
    private static final String AMAP_API_URL = "https://restapi.amap.com/v3/geocode/regeo";

    // 高德API Key
    private static final String API_KEY = "7b6d80895b9fa2b898ab63047392448d";

    @Autowired
    private IDeviceService deviceService;

    /**
     * 解析经纬度
     * @param StrRS232 报文数据
     */
    public void LNGAndLAT(String StrRS232,String clientId){
        log.info("解析经纬度的数据为：{}",StrRS232);
        // 定义正则表达式匹配 LNG 和 LAT
        Pattern lngPattern = Pattern.compile("LNG = (\\d+\\.\\d+)");
        Pattern latPattern = Pattern.compile("LAT = (\\d+\\.\\d+)");
        Matcher lngMatcher = lngPattern.matcher(StrRS232);
        Matcher latMatcher = latPattern.matcher(StrRS232);
        if (lngMatcher.find() && latMatcher.find()) {
            String lng = lngMatcher.group(1);  // 提取 LNG 的值
            String lat = latMatcher.group(1);  // 提取 LAT 的值
            log.info("WGS-84经度坐标是：【{}】",lng);
            log.info("WGS-84纬度坐标是：【{}】",lat);
            double[] doubles = GpsCoordinateUtils.calWGS84toGCJ02(Double.parseDouble(lat),Double.parseDouble(lng));
            log.info("将WGS-84坐标转换为GCJ-02坐标为：{}",doubles);
            String addressByLocation = RestapiMessage.getAddressByLocation(String.valueOf(doubles[1]), String.valueOf(doubles[0]));
            if (null != addressByLocation || !addressByLocation.contains("[")) {
                log.info("经纬度地址是：【{}】",addressByLocation);
                //异步修改设备的经纬度地址
                AsyncManager.me().execute(new TimerTask() {
                    @Override
                    public void run() {
                        Device device = new Device();
                        device.setSerialNumber(clientId);
                        device.setLatitude(BigDecimal.valueOf(doubles[0]));
                        device.setLongitude(BigDecimal.valueOf(doubles[1]));
                        device.setNetworkAddress(addressByLocation);
                        deviceService.deviceLongitudeAndLatitude(device);
                    }
                });
            }
        } else {
            log.error("未找到 经度 或 纬度 的值");
        }
    }

    /**
     * 根据经纬度获取地址信息
     * @param longitude 经度
     * @param latitude 纬度
     * @return 地址信息
     */
    public static String getAddressByLocation(String longitude, String latitude) {
        String location = longitude + "," + latitude;
        String url = AMAP_API_URL + "?location=" + location + "&key=" + API_KEY + "&radius=1000&extensions=base";

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(url);

            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String result = EntityUtils.toString(entity);
                    return parseAddress(result);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 解析高德API返回的JSON数据
     * @param jsonString 高德API返回的JSON字符串
     * @return 格式化后的地址信息
     */
    private static String parseAddress(String jsonString) {
        JSONObject jsonObject = JSON.parseObject(jsonString);
        if ("1".equals(jsonObject.getString("status"))) {
            JSONObject regeocode = jsonObject.getJSONObject("regeocode");
            if (regeocode != null) {
                return regeocode.getString("formatted_address");
            }
        }
        return null;
    }
}
